package cn.mini.mybatis.mybatis.builder;


import cn.mini.mybatis.mybatis.mapping.MappedStatement;
import cn.mini.mybatis.mybatis.mapping.SqlCommandType;
import cn.mini.mybatis.mybatis.mapping.SqlSource;
import cn.mini.mybatis.mybatis.session.Configuration;


/**
 * MapperBuilderAssistant 类继承自 BaseBuilder，用于辅助构建 Mapper 映射器相关信息。
 * 它主要负责管理命名空间，为 SQL 语句的 ID 添加命名空间前缀，
 * 并协助将 MappedStatement 对象添加到 Configuration 中。
 */
@SuppressWarnings("all")
public class MapperBuilderAssistant extends BaseBuilder {

    /**
     * 当前 Mapper 文件的命名空间，用于唯一标识一组 SQL 语句。
     */
    private String currentNamespace;
    /**
     * 当前正在处理的 Mapper XML 文件的资源路径。
     */
    private String resource;

    /**
     * 构造函数，初始化 MapperBuilderAssistant 对象。
     *
     * @param configuration MyBatis 的配置对象，包含全局配置信息。
     * @param resource      当前正在处理的 Mapper XML 文件的资源路径。
     */
    public MapperBuilderAssistant(Configuration configuration, String resource) {
        super(configuration);
        this.resource = resource;
    }

    /**
     * 获取当前 Mapper 文件的命名空间。
     *
     * @return 当前命名空间的字符串表示。
     */
    public String getCurrentNamespace() {
        return currentNamespace;
    }

    /**
     * 设置当前 Mapper 文件的命名空间。
     *
     * @param currentNamespace 要设置的命名空间字符串。
     */
    public void setCurrentNamespace(String currentNamespace) {
        this.currentNamespace = currentNamespace;
    }

    /**
     * 为给定的基础 ID 应用当前命名空间，生成唯一的 ID。
     *
     * @param base        基础 ID，可能是 SQL 语句的 ID。
     * @param isReference 是否为引用类型的 ID。
     * @return 应用命名空间后的完整 ID，如果 base 为 null 则返回 null。
     */
    public String applyCurrentNamespace(String base, boolean isReference) {
        // 若基础 ID 为空，直接返回 null
        if (base == null) {
            return null;
        }
        // 如果是引用类型的 ID 且已经包含点号，则认为已经是完整 ID，直接返回
        if (isReference) {
            if (base.contains(".")) {
                return base;
            }
        }
        // 为基础 ID 添加当前命名空间前缀
        return currentNamespace + "." + base;
    }

    /**
     * 添加映射器语句，将 SQL 语句相关信息封装到 MappedStatement 对象并添加到配置中。
     *
     * @param id             SQL 语句的基础 ID。
     * @param sqlCommandType SQL 语句的类型，如 SELECT、INSERT 等。
     * @param boundSql       封装了 SQL 语句及其参数信息的 BoundSql 对象。
     * @return 构建好的 MappedStatement 对象。
     */
    public MappedStatement addMappedStatement(
            String id,
            SqlCommandType sqlCommandType,
            SqlSource sqlSource,
            Class<?> resultType) {
        // 为 SQL 语句的 ID 应用当前命名空间，生成唯一 ID
        id = applyCurrentNamespace(id, false);
        // 创建 MappedStatement 构建器，初始化 MappedStatement 对象
        MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration,
                id, sqlCommandType, sqlSource,resultType);
        // 构建 MappedStatement 对象
        MappedStatement statement = statementBuilder.build();
        // 将构建好的 MappedStatement 对象添加到配置中
        configuration.addMappedStatement(statement);
        return statement;
    }
}